/**
 * @file SDPHandler.cpp
 * @author Derek Liu (yjkhtddx@sina.com)
 * @brief SDP工具
 * @version 0.0.1
 * @date 2020-07-18
 * 
 * @coryright Copyright Sci-Tech Laboratories (c) 2020
 * 
 */

#include "SDPHandler.hpp"
#include <osipparser2/osip_message.h>
#include <osipparser2/sdp_message.h>

int SDPHandler::ParseSdp(const char *buf, SDPHandler::sdp_description_t &sdp_desc)
{
    if (buf == nullptr)
    {
        return -1;
    }

    sdp_message_t *osip_sdp;
    sdp_message_init(&osip_sdp);
    int r = sdp_message_parse(osip_sdp, buf);
    if (r != 0)
    {
        sdp_message_free(osip_sdp);
        return -2;
    }

    sdp_desc.v_version = osip_sdp->v_version;
    sdp_desc.o_addr = osip_sdp->o_addr;
    sdp_desc.o_addrtype = osip_sdp->o_addrtype;
    sdp_desc.o_nettype = osip_sdp->o_nettype;
    sdp_desc.o_sess_version = osip_sdp->o_sess_version;
    sdp_desc.o_sessid = osip_sdp->o_sess_id;
    sdp_desc.s_sess_name = osip_sdp->s_name;
    sdp_desc.u_uri = osip_sdp->u_uri;
    sdp_desc.c_addr = osip_sdp->c_connection->c_addr;
    sdp_desc.c_addrtype = osip_sdp->c_connection->c_addrtype;
    sdp_desc.c_nettype = osip_sdp->c_connection->c_nettype;

    sdp_time_descr_t *t_ele = (sdp_time_descr_t *)osip_list_get(&(osip_sdp->t_descrs), 0);
    if (t_ele != nullptr)
    {
        sdp_desc.t_startime = t_ele->t_start_time;
        sdp_desc.t_endtime = t_ele->t_stop_time;
    }

    sdp_media_t *m_ele = (sdp_media_t *)osip_list_get(&(osip_sdp->m_medias), 0);
    if (m_ele != nullptr)
    {
        sdp_desc.m_media = m_ele->m_media;
        sdp_desc.m_tmode = m_ele->m_proto;
        sdp_desc.m_port = m_ele->m_port;
        ///< TODO maybe need to reparse "m" oneself;
    }

    for (uint32_t i = 0; i < osip_sdp->a_attributes.nb_elt; ++i)
    {
        sdp_attribute_t *a_ele = (sdp_attribute_t *)osip_list_get(&(osip_sdp->a_attributes), i);
        if (a_ele != nullptr)
        {
            sdp_desc.a_attrimap.insert(std::make_pair(a_ele->a_att_field, a_ele->a_att_value));
        }
    }

    ///< TODO parse y= f=

    sdp_desc.print();

    sdp_message_free(osip_sdp);

    return 0;
}

/**
v=0
o=34020000002000000001 0 0 IN IP4 10.0.0.42
s=Play
c=IN IP4 10.0.0.42
t=0 0
m=video 30016 RTP/AVP 96 97 98
a=recvonly
a=rtpmap:96 PS/90000
a=rtpmap:97 MPEG4/90000
a=rtpmap:98 H264/90000
y=0102000001
*/
int SDPHandler::AssembleSdp(std::string &sdp)
{
    // int SDPHandler::AssembleSdp(std::string &sdp, const sdp_description_t &sdp_desc)
    sdp_message_t *osip_sdp;
    sdp_message_init(&osip_sdp);

    sdp_message_v_version_set(osip_sdp, osip_strdup("0"));
    osip_sdp->o_username = osip_strdup("34020000002000000001");
    osip_sdp->o_sess_id = osip_strdup("0");
    osip_sdp->o_sess_version = osip_strdup("0");
    osip_sdp->o_nettype = osip_strdup("IN");
    osip_sdp->o_addrtype = osip_strdup("IP4");
    osip_sdp->o_addr = osip_strdup("10.0.0.42");
    sdp_message_c_connection_add(osip_sdp, -1, osip_strdup("IN"), osip_strdup("IP4"), osip_strdup("10.0.0.42"), nullptr, nullptr);
    sdp_message_s_name_set(osip_sdp, osip_strdup("Play"));
    sdp_message_t_time_descr_add(osip_sdp, osip_strdup("0"), osip_strdup("0"));
    sdp_message_m_media_add(osip_sdp, osip_strdup("video"), osip_strdup("30016"), osip_strdup("96 97 98"), osip_strdup("RTP/AVP"));
    sdp_message_a_attribute_add(osip_sdp, -1, osip_strdup("recvonly"), nullptr);
    sdp_message_a_attribute_add(osip_sdp, -1, osip_strdup("rtpmap"), osip_strdup("96 PS/90000"));
    sdp_message_a_attribute_add(osip_sdp, -1, osip_strdup("rtpmap"), osip_strdup("97 MPEG4/90000"));
    sdp_message_a_attribute_add(osip_sdp, -1, osip_strdup("rtpmap"), osip_strdup("98 H264/90000"));
    char *sdpPtr = nullptr;
    int ret = sdp_message_to_str(osip_sdp, &sdpPtr);
    if (sdpPtr)
    {
        sdp = std::string(sdpPtr);
        osip_free(sdpPtr);
    }
    stl::debug("[%d]>>>\n%s\n<<<", ret, sdp.c_str());
    sdp_message_free(osip_sdp);
    stl::debug(">>>忒不好用了<<<");
    return 0;
}

/**
v=0
o=34020000002000000001 0 0 IN IP4 10.0.0.42
s=Play
c=IN IP4 10.0.0.42
t=0 0
m=video 30016 RTP/AVP 96 97 98
a=recvonly
a=rtpmap:96 PS/90000
a=rtpmap:97 MPEG4/90000
a=rtpmap:98 H264/90000
y=0102000001
*/
std::string SDPHandler::generateSDP(std::string username,std::string rtpIp,uint16_t rtpPort,std::string ssrc)
{
    return "v=0\r\no="+username+" 0 0 IN IP4 "+rtpIp+"\r\ns=Play\r\nc=IN IP4 "+rtpIp+"\r\nt=0 0\r\nm=video "+std::to_string(rtpPort)+" RTP/AVP 96 97 98\r\na=recvonly\r\na=rtpmap:96 PS/90000\r\na=rtpmap:97 MPEG4/90000\r\na=rtpmap:98 H264/90000\r\ny="+ssrc+"\r\n";
}
